﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;
using Stauffware.Common.Core;
using Stauffware.Common.Xml;
using Stauffware.Common.Xml.Xerialization;

namespace XmlUnitTests
{
	public class _Program
	{
		// The Xml_UnitTests project is intended primarily for use with NUnit.
		// It is built as a console app rather than a DLL to facilitate ad-hoc
		// testing under the debugger.

		public static void Main (string[] args)
		{
			Test_Immutable();
		//	Test_Objects();
		//	TestCData();
		//	Test_Z2();
		//	TestIgnoreCase();
		}

		//-----------------------------------------------------------------------------

		private static void TestIgnoreCase ( )
		{
			const string filePath = "..\\..\\TestData\\IgnoreCase.xml";

			bool noIgnoreOK = ! TryIgnoreCase(filePath, false);
			bool ignoreOK = TryIgnoreCase(filePath, true);

			if (ignoreOK && noIgnoreOK)
				Console.WriteLine("\r\nTestIgnoreCase - ok!");
			else Console.Write("\r\nTestIgnoreCase - FAILED; see above for details");
		}

		//-----------------------------------------------------------------------------
		// returns true if no errors; false if exception thrown

		private static bool TryIgnoreCase (string filePath, bool ignoreCase)
		{
			Console.WriteLine("\r\nTryIgnoreCase (" + filePath + ", " + ignoreCase.ToString() + ")\r\n");

			// setup

			XerialContext context = new XerialContext(ignoreCase);
			context.DebugLog = Console.Out;
			context.TypeMappings.AddIfNeeded(Zoo_1.Zoo.XerialTypes);

			// read from XML file

			StreamReader sr = new StreamReader(filePath);
			try
			{
				Zoo_1.Zoo zoo1 = (Zoo_1.Zoo) context.ReadFromXml(sr);
				return true;
			}
			catch (Exception x)
			{
				Console.WriteLine(ErrorUtils.DumpExceptionChain(x));
				return false;
			}
			finally
			{
				sr.Close();
			}
		}

		//-----------------------------------------------------------------------------

		private static void TestCData ( )
		{
			const string filePath = "..\\..\\TestData\\CData_1.xml";

			// setup

			XerialContext context = new XerialContext(true);
			context.DebugLog = Console.Out;
			context.TypeMappings.AddIfNeeded(Zoo_1.Zoo.XerialTypes);

			// read from XML file

			StreamReader sr = new StreamReader(filePath);
			Zoo_1.Zoo zoo1 = (Zoo_1.Zoo) context.ReadFromXml(sr);
			sr.Close();

			Console.WriteLine();

			// write to XML

			context.WriteToXml(zoo1, Console.Out);

			Console.WriteLine();

		}

		//-----------------------------------------------------------------------------

		private static void Test_ErrorHandling (string xmlFilePath)
		{
			try
			{
				NiceXmlReader nxr = new NiceXmlReader(xmlFilePath);
				while (nxr.Read())
					;
			}
			catch (Exception x)
			{
				ErrorUtils.DumpExceptionChain(x, Console.Out);
			}
		}

		//-----------------------------------------------------------------------------

		private static void Test_Immutable ( )
		{
			XerialContext context = new XerialContext(true);
			context.DebugLog = Console.Out;
			context.TypeMappings.AddIfNeeded(typeof(TestObjects.ConSct_1));
			context.TypeMappings.Dump(Console.Out, false);

			TestObjects.ConSct_1 obj1 = new TestObjects.ConSct_1(2.141M, "fjlbx");

			Console.WriteLine("obj1: " + obj1.ToString());

			// write to XML

			StringWriter sw = new StringWriter();
			context.WriteToXml(obj1, sw);

			Console.WriteLine("\n" + sw.ToString() + "\n");

			// read from XML

			StringReader sr = new StringReader(sw.ToString());
			TestObjects.ConSct_1 obj2 = (TestObjects.ConSct_1) context.ReadFromXml(
									sr, null, XmlUtils.ErrorReporter(Console.Out));

			Console.WriteLine("obj1: " + obj1.ToString());
			Console.WriteLine("obj2: " + obj2.ToString());

			Console.WriteLine();
		}

		//-----------------------------------------------------------------------------

		private static void Test_Objects ()
		{
			// setup

			TestObjects.MainClass obj1 = new TestObjects.MainClass();

			XerialContext context = new XerialContext(true);
			context.DebugLog = Console.Out;
			TestObjects.MainClass.InitializeContext(context);

			// write to XML

			StringWriter sw = new StringWriter();
			context.WriteToXml(obj1, sw);

			Console.WriteLine("\n" + sw.ToString() + "\n");

			// read from XML

			StringReader sr = new StringReader(sw.ToString());
			TestObjects.MainClass obj2 = (TestObjects.MainClass) context.ReadFromXml(sr, 
											null, XmlUtils.ErrorReporter(Console.Out));

			Console.WriteLine();

			// compare old & new objects

			KellermanSoftware.CompareNetObjects.CompareObjects comparer = 
						new KellermanSoftware.CompareNetObjects.CompareObjects();
			comparer.MaxDifferences = 100;
			comparer.CompareStaticFields = false;
			comparer.CompareStaticProperties = false;

			if (comparer.Compare(obj1, obj2))
				Console.WriteLine("Old and new objects match!");
			else Console.WriteLine(comparer.DifferencesString);
		}

		//-----------------------------------------------------------------------------

		private static void Test_Z2 ( )
		{
			const string filePath = "Test_Z2.xml";

			// setup

			Zoo_1.Zoo zoo1 = Zoo_1.Zoo.CreateSample1();

			XerialContext context = new XerialContext(true);
			context.DebugLog = Console.Out;
			context.TypeMappings.AddIfNeeded(Zoo_1.Zoo.XerialTypes);

			// write to XML

			StreamWriter sw = new StreamWriter(filePath);
			context.WriteToXml(zoo1, sw);
			sw.Close();

			// read from XML

			StreamReader sr = new StreamReader(filePath);
			Zoo_1.Zoo zoo2 = (Zoo_1.Zoo) context.ReadFromXml(sr);
			sr.Close();

			Console.WriteLine();

			// compare old & new objects

			KellermanSoftware.CompareNetObjects.CompareObjects comparer = 
						new KellermanSoftware.CompareNetObjects.CompareObjects();
			comparer.CompareStaticFields = false;
			comparer.CompareStaticProperties = false;

			if (comparer.Compare(zoo1, zoo2))
				Console.WriteLine("Old and new zoos match!");
			else Console.WriteLine(comparer.DifferencesString);

		}

		//-----------------------------------------------------------------------------

		private static void Test_Z1()
		{
			// setup

			Zoo_1.Zoo zoo1 = Zoo_1.Zoo.CreateSample1();

			XerialContext context = new XerialContext(true);
			context.DebugLog = Console.Out;
			context.TypeMappings.AddIfNeeded(Zoo_1.Zoo.XerialTypes);

			// write to XML

			StringWriter sw = new StringWriter();
			context.WriteToXml(zoo1, sw);

			Console.WriteLine("\n" + sw.ToString() + "\n");

			// read from XML

			StringReader sr = new StringReader(sw.ToString());
			Zoo_1.Zoo zoo2 = (Zoo_1.Zoo) context.ReadFromXml(sr, null, XmlUtils.ErrorReporter(Console.Out));

			Console.WriteLine();

			// compare old & new objects

			KellermanSoftware.CompareNetObjects.CompareObjects comparer = 
						new KellermanSoftware.CompareNetObjects.CompareObjects();
			comparer.CompareStaticFields = false;
			comparer.CompareStaticProperties = false;

			if (comparer.Compare(zoo1, zoo2))
				Console.WriteLine("Old and new zoos match!");
			else Console.WriteLine(comparer.DifferencesString);

		}

		//-----------------------------------------------------------------------------
	}
}
